package com.smart.community.property.service.impl;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.enums.SystemStatusEnum;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.property.entity.RepairProgress;
import com.smart.community.property.mapper.RepairProgressMapper;
import com.smart.community.property.service.IRepairProgressService;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 维修工单进度记录服务实现类
 * 
 * 严格按照《Java后端SpringBoot代码开发规范.md》Entity规范实现：
 * - 功能单一原则：Service层负责业务逻辑处理，Entity层只负责数据库字段映射
 * - 类型一致性：确保与Entity字段类型完全一致，progressType和status使用String类型
 * - 生产环境标准：移除throws Exception声明，使用统一异常处理
 * - 完整注释：所有方法都有完整的JavaDoc注释
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 2.0.0 - 根据新Entity规范调整
 */
@Slf4j
@Service
public class RepairProgressServiceImpl extends ServiceImpl<RepairProgressMapper, RepairProgress> implements IRepairProgressService {

    @Autowired
    private RepairProgressMapper repairProgressMapper;

    @Override
    @GlobalTransactional
    public boolean saveProgress(RepairProgress progress) {
        try {
            // 参数校验
            if (progress == null) {
                log.warn("保存进度记录失败：进度记录对象为空");
                return false;
            }

            // 设置默认值
            if (progress.getStatus() == null) {
                progress.setStatus(SystemStatusEnum.ENABLED.getCode());
            }
            if (progress.getCreateTime() == null) {
                progress.setCreateTime(LocalDateTime.now());
            }
            if (progress.getProgressTime() == null) {
                progress.setProgressTime(LocalDateTime.now());
            }

            // 自动设置排序字段
            if (progress.getSortOrder() == null) {
                int nextOrder = getNextSortOrder(progress.getOrderId());
                progress.setSortOrder(nextOrder);
            }

            int result = repairProgressMapper.insertProgress(progress);
            if (result > 0) {
                log.info("保存进度记录成功，工单ID: {}, 进度类型: {}, 进度ID: {}", 
                        progress.getOrderId(), progress.getProgressType(), progress.getId());
                return true;
            } else {
                log.warn("保存进度记录失败，工单ID: {}, 进度类型: {}", 
                        progress.getOrderId(), progress.getProgressType());
                return false;
            }
        } catch (BusinessException e) {
            log.warn("保存进度记录业务异常，工单ID: {}", progress != null ? progress.getOrderId() : "null", e);
            throw e;
        } catch (Exception e) {
            log.error("保存进度记录系统异常，工单ID: {}", progress != null ? progress.getOrderId() : "null", e);
            throw new BusinessException("保存进度记录失败: " + e.getMessage());
        }
    }

    @Override
    @GlobalTransactional
    public boolean createProgress(Long orderId, String orderNo, Integer progressType, String progressTitle,
                                 String progressContent, Long operatorId, String operatorName) {
        return createProgressWithRepairman(orderId, orderNo, progressType, progressTitle, progressContent,
                operatorId, operatorName, null, null, LocalDateTime.now());
    }

    @Override
    @GlobalTransactional
    public boolean createProgressWithRepairman(Long orderId, String orderNo, Integer progressType, String progressTitle,
                                              String progressContent, Long operatorId, String operatorName,
                                              Long repairmanId, String repairmanName, LocalDateTime progressTime) {
        try {
            // 参数校验
            if (orderId == null || !StringUtils.hasText(orderNo) || progressType == null) {
                log.warn("创建进度记录参数不完整，工单ID: {}, 工单号: {}, 进度类型: {}", orderId, orderNo, progressType);
                return false;
            }

            RepairProgress progress = new RepairProgress();
            progress.setOrderId(orderId);
            progress.setOrderNo(orderNo);
            progress.setProgressType(progressType);
            progress.setProgressTitle(progressTitle);
            progress.setProgressContent(progressContent);
            progress.setProgressTime(progressTime != null ? progressTime : LocalDateTime.now());
            progress.setOperatorId(operatorId);
            progress.setOperatorName(operatorName);
            progress.setRepairmanId(repairmanId);
            progress.setRepairmanName(repairmanName);

            return saveProgress(progress);
        } catch (BusinessException e) {
            log.warn("创建进度记录业务异常，工单ID: {}, 进度类型: {}", orderId, progressType, e);
            throw e;
        } catch (Exception e) {
            log.error("创建进度记录系统异常，工单ID: {}, 进度类型: {}", orderId, progressType, e);
            throw new BusinessException("创建进度记录失败: " + e.getMessage());
        }
    }

    @Override
    public List<RepairProgress> getProgressListByOrderId(Long orderId) {
        try {
            if (orderId == null) {
                log.warn("查询工单进度记录失败：工单ID为空");
                return Collections.emptyList();
            }
            List<RepairProgress> result = repairProgressMapper.selectByOrderId(orderId);
            log.debug("查询工单进度记录成功，工单ID: {}, 记录数量: {}", orderId, result.size());
            return result;
        } catch (BusinessException e) {
            log.warn("查询工单进度记录业务异常，工单ID: {}", orderId, e);
            throw e;
        } catch (Exception e) {
            log.error("查询工单进度记录系统异常，工单ID: {}", orderId, e);
            throw new BusinessException("查询工单进度记录失败: " + e.getMessage());
        }
    }

    @Override
    public List<RepairProgress> getProgressListByOrderNo(String orderNo) {
        try {
            if (!StringUtils.hasText(orderNo)) {
                log.warn("查询工单进度记录失败：工单号为空");
                return Collections.emptyList();
            }
            List<RepairProgress> result = repairProgressMapper.selectByOrderNo(orderNo);
            log.debug("查询工单进度记录成功，工单号: {}, 记录数量: {}", orderNo, result.size());
            return result;
        } catch (BusinessException e) {
            log.warn("查询工单进度记录业务异常，工单号: {}", orderNo, e);
            throw e;
        } catch (Exception e) {
            log.error("查询工单进度记录系统异常，工单号: {}", orderNo, e);
            throw new BusinessException("查询工单进度记录失败: " + e.getMessage());
        }
    }

    @Override
    public RepairProgress getLatestProgressByOrderId(Long orderId) {
        try {
            if (orderId == null) {
                log.warn("查询工单最新进度记录失败：工单ID为空");
                return null;
            }
            RepairProgress result = repairProgressMapper.selectLatestByOrderId(orderId);
            log.debug("查询工单最新进度记录成功，工单ID: {}, 进度ID: {}", orderId, result != null ? result.getId() : "null");
            return result;
        } catch (BusinessException e) {
            log.warn("查询工单最新进度记录业务异常，工单ID: {}", orderId, e);
            throw e;
        } catch (Exception e) {
            log.error("查询工单最新进度记录系统异常，工单ID: {}", orderId, e);
            throw new BusinessException("查询工单最新进度记录失败: " + e.getMessage());
        }
    }

    @Override
    public RepairProgress getProgressByOrderIdAndType(Long orderId, Integer progressType) {
        try {
            if (orderId == null || progressType == null) {
                log.warn("查询工单指定类型进度记录失败：工单ID或进度类型为空，工单ID: {}, 进度类型: {}", orderId, progressType);
                return null;
            }
            RepairProgress result = repairProgressMapper.selectByOrderIdAndType(orderId, progressType);
            log.debug("查询工单指定类型进度记录成功，工单ID: {}, 进度类型: {}, 进度ID: {}", 
                    orderId, progressType, result != null ? result.getId() : "null");
            return result;
        } catch (BusinessException e) {
            log.warn("查询工单指定类型进度记录业务异常，工单ID: {}, 进度类型: {}", orderId, progressType, e);
            throw e;
        } catch (Exception e) {
            log.error("查询工单指定类型进度记录系统异常，工单ID: {}, 进度类型: {}", orderId, progressType, e);
            throw new BusinessException("查询工单指定类型进度记录失败: " + e.getMessage());
        }
    }

    @Override
    @GlobalTransactional
    public boolean deleteProgressByOrderId(Long orderId) {
        try {
            if (orderId == null) {
                log.warn("删除工单进度记录失败：工单ID为空");
                return false;
            }
            int result = repairProgressMapper.deleteByOrderId(orderId);
            log.info("删除工单进度记录成功，工单ID: {}, 删除数量: {}", orderId, result);
            return result > 0;
        } catch (BusinessException e) {
            log.warn("删除工单进度记录业务异常，工单ID: {}", orderId, e);
            throw e;
        } catch (Exception e) {
            log.error("删除工单进度记录系统异常，工单ID: {}", orderId, e);
            throw new BusinessException("删除工单进度记录失败: " + e.getMessage());
        }
    }

    @Override
    public int countProgressByOrderId(Long orderId) {
        try {
            if (orderId == null) {
                log.warn("统计工单进度记录数量失败：工单ID为空");
                return 0;
            }
            int result = repairProgressMapper.countByOrderId(orderId);
            log.debug("统计工单进度记录数量成功，工单ID: {}, 数量: {}", orderId, result);
            return result;
        } catch (BusinessException e) {
            log.warn("统计工单进度记录数量业务异常，工单ID: {}", orderId, e);
            throw e;
        } catch (Exception e) {
            log.error("统计工单进度记录数量系统异常，工单ID: {}", orderId, e);
            throw new BusinessException("统计工单进度记录数量失败: " + e.getMessage());
        }
    }

    @Override
    public List<RepairProgress> getProgressListByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        try {
            if (startTime == null || endTime == null) {
                log.warn("查询时间范围内进度记录失败：开始时间或结束时间为空，开始时间: {}, 结束时间: {}", startTime, endTime);
                return Collections.emptyList();
            }
            List<RepairProgress> result = repairProgressMapper.selectByTimeRange(startTime, endTime);
            log.debug("查询时间范围内进度记录成功，开始时间: {}, 结束时间: {}, 记录数量: {}", 
                    startTime, endTime, result.size());
            return result;
        } catch (BusinessException e) {
            log.warn("查询时间范围内进度记录业务异常，开始时间: {}, 结束时间: {}", startTime, endTime, e);
            throw e;
        } catch (Exception e) {
            log.error("查询时间范围内进度记录系统异常，开始时间: {}, 结束时间: {}", startTime, endTime, e);
            throw new BusinessException("查询时间范围内进度记录失败: " + e.getMessage());
        }
    }

    @Override
    public List<RepairProgress> getProgressListByRepairmanId(Long repairmanId, LocalDateTime startTime, LocalDateTime endTime) {
        try {
            if (repairmanId == null) {
                log.warn("查询维修人员进度记录失败：维修人员ID为空");
                return Collections.emptyList();
            }
            if (startTime == null || endTime == null) {
                log.warn("查询维修人员进度记录失败：开始时间或结束时间为空，维修人员ID: {}, 开始时间: {}, 结束时间: {}",
                        repairmanId, startTime, endTime);
                return Collections.emptyList();
            }
            List<RepairProgress> result = repairProgressMapper.selectByRepairmanId(repairmanId, startTime, endTime);
            log.debug("查询维修人员进度记录成功，维修人员ID: {}, 开始时间: {}, 结束时间: {}, 记录数量: {}",
                    repairmanId, startTime, endTime, result.size());
            return result;
        } catch (BusinessException e) {
            log.warn("查询维修人员进度记录业务异常，维修人员ID: {}", repairmanId, e);
            throw e;
        } catch (Exception e) {
            log.error("查询维修人员进度记录系统异常，维修人员ID: {}", repairmanId, e);
            throw new BusinessException("查询维修人员进度记录失败: " + e.getMessage());
        }
    }

    @Override
    @GlobalTransactional
    public boolean batchCreateProgress(List<RepairProgress> progressList) {
        try {
            if (progressList == null || progressList.isEmpty()) {
                log.warn("批量创建进度记录失败：进度记录列表为空");
                return false;
            }

            // 为每个进度记录设置默认值
            for (RepairProgress progress : progressList) {
                if (progress.getStatus() == null) {
                    progress.setStatus(SystemStatusEnum.ENABLED.getCode());
                }
                if (progress.getCreateTime() == null) {
                    progress.setCreateTime(LocalDateTime.now());
                }
                if (progress.getProgressTime() == null) {
                    progress.setProgressTime(LocalDateTime.now());
                }
                if (progress.getSortOrder() == null) {
                    int nextOrder = getNextSortOrder(progress.getOrderId());
                    progress.setSortOrder(nextOrder);
                }
            }

            int result = repairProgressMapper.batchInsertProgress(progressList);
            if (result > 0) {
                log.info("批量创建进度记录成功，数量: {}", result);
                return true;
            } else {
                log.warn("批量创建进度记录失败，预期数量: {}, 实际插入数量: {}", progressList.size(), result);
                return false;
            }
        } catch (BusinessException e) {
            log.warn("批量创建进度记录业务异常，预期数量: {}", progressList != null ? progressList.size() : 0, e);
            throw e;
        } catch (Exception e) {
            log.error("批量创建进度记录系统异常，预期数量: {}", progressList != null ? progressList.size() : 0, e);
            throw new BusinessException("批量创建进度记录失败: " + e.getMessage());
        }
    }

    @Override
    @GlobalTransactional
    public boolean updateProgressContent(Long orderId, String progressContent) {
        try {
            if (orderId == null || !StringUtils.hasText(progressContent)) {
                log.warn("更新进度记录内容参数不完整，工单ID: {}, 进度内容: {}", orderId, progressContent);
                return false;
            }

            // 获取最新的进度记录
            RepairProgress latestProgress = getLatestProgressByOrderId(orderId);
            if (latestProgress == null) {
                log.warn("未找到工单的最新进度记录，工单ID: {}", orderId);
                return false;
            }

            // 更新进度内容
            int result = repairProgressMapper.updateProgressContent(latestProgress.getId(), progressContent);
            if (result > 0) {
                log.info("更新进度记录内容成功，工单ID: {}, 进度ID: {}", orderId, latestProgress.getId());
                return true;
            } else {
                log.warn("更新进度记录内容失败，工单ID: {}, 进度ID: {}", orderId, latestProgress.getId());
                return false;
            }
        } catch (BusinessException e) {
            log.warn("更新进度记录内容业务异常，工单ID: {}", orderId, e);
            throw e;
        } catch (Exception e) {
            log.error("更新进度记录内容系统异常，工单ID: {}", orderId, e);
            throw new BusinessException("更新进度记录内容失败: " + e.getMessage());
        }
    }

    /**
     * 获取下一个排序序号
     * 
     * @param orderId 工单ID
     * @return 下一个排序序号
     */
    private int getNextSortOrder(Long orderId) {
        try {
            if (orderId == null) {
                log.warn("获取下一个排序序号失败：工单ID为空");
                return 1;
            }
            int count = countProgressByOrderId(orderId);
            int nextOrder = count + 1;
            log.debug("获取下一个排序序号成功，工单ID: {}, 当前数量: {}, 下一个序号: {}", orderId, count, nextOrder);
            return nextOrder;
        } catch (Exception e) {
            log.warn("获取下一个排序序号失败，使用默认值1，工单ID: {}", orderId, e);
            return 1;
        }
    }
} 
